//
//  GLGalleryLayout.m
//  Gallery
//
//  Created by admin on 2021/12/28.
//

#import "GLGalleryLayout.h"
#import <objc/runtime.h>

@implementation GLGalleryLayout{
    NSIndexPath *_centralIndexPath;
    CGRect _cframe;
}

+ (instancetype)layoutWithPreferredScale:(CGFloat)scale edgeSpace:(CGFloat)space{
    GLGalleryLayout *layout = [GLGalleryLayout new];
    layout.preferredScale = scale;
    layout.preferredEdgeSpace = space;
    return layout;
}

-(id)init{
    self = [super init];
    if (self) {
        self.scrollDirection = UICollectionViewScrollDirectionHorizontal;//设置为水平显示
        self.preferredScale = 0.87;
        self.preferredEdgeSpace = 15;
    }
    return self;
}

- (void)prepareLayout{
    [super prepareLayout];
    CGSize size = self.itemSize;
    NSInteger minimumLineSpacing = floor((CGRectGetWidth(self.collectionView.bounds)/2 - size.width/2) - size.width * (1-self.preferredScale)/2 - self.preferredEdgeSpace);
    if (minimumLineSpacing > size.width){
        self.minimumLineSpacing = MAX(10, minimumLineSpacing%((NSInteger)size.width));
    }else{
        self.minimumLineSpacing = minimumLineSpacing;
    }
    
    CGFloat left = floor(CGRectGetWidth(self.collectionView.bounds)/2 - size.width/2);
    CGFloat top = floor(CGRectGetHeight(self.collectionView.bounds)/2 - size.height/2);
    self.collectionView.contentInset = UIEdgeInsetsMake(top, left, top, left);
}
 
-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{
    //proposedContentOffset是没有设置对齐时本应该停下的位置（collectionView落在屏幕左上角的点坐标）
    CGFloat offsetAdjustment = MAXFLOAT;//初始化调整距离为无限大
    CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0);//collectionView落在屏幕中点的x坐标
    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);//collectionView落在屏幕的大小
    NSArray* array = [super layoutAttributesForElementsInRect:targetRect];//获得落在屏幕的所有cell的属性
    
    //对当前屏幕中的UICollectionViewLayoutAttributes逐个与屏幕中心进行比较，找出最接近中心的一个
    for (UICollectionViewLayoutAttributes* layoutAttributes in array) {
        CGFloat itemHorizontalCenter = layoutAttributes.center.x;
        if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) {
            offsetAdjustment = itemHorizontalCenter - horizontalCenter;
        }
    }
    //调整
    return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
 
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    NSArray *array = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
    CGRect visibleRect;
    visibleRect.origin = self.collectionView.contentOffset;
    visibleRect.size = self.collectionView.bounds.size;
    
    //遍历所有布局属性
    for (UICollectionViewLayoutAttributes* attributes in array) {
        //如果cell在屏幕上则进行缩放
        if (CGRectIntersectsRect(attributes.frame, rect)) {
            CGFloat zoom = [self scaleForCell:attributes];
            if (fabs(zoom - 1) <= 0.001){
                self->_centralIndexPath = attributes.indexPath;
            }
            attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
            attributes.zIndex = 1;
        }
    }
    return array;
}
- (CGFloat)scaleForCell:(UICollectionViewLayoutAttributes* )attributes{
    CGSize size = self.itemSize;

    CGFloat d = fabs(CGRectGetMidX(attributes.frame) - self.collectionView.contentOffset.x - CGRectGetWidth(self.collectionView.bounds)/2)/(size.width + self.minimumLineSpacing);
    CGFloat scale = 1 - d * (1 - self.preferredScale) ;
    return scale;
}

/**
 *  只要显示的边界发生改变就重新布局:
 内部会重新调用prepareLayout和layoutAttributesForElementsInRect方法获得所有cell的布局属性
 */
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    return YES;
}

- (NSIndexPath *)centralIndexPath{
    return _centralIndexPath;
}


- (void)invalidateLayout{
    [super invalidateLayout];
    
    ///解决collectionview frame改变导致当前的cell不居中
    ///强行调整当前indexpath居中
    if (CGRectEqualToRect(self->_cframe, self.collectionView.frame)){
        return;
    }
    
    self->_cframe = self.collectionView.frame;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.collectionView scrollToItemAtIndexPath:self->_centralIndexPath?:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
    });
}

@end
